package com.xidian.zhiancloud.service.chemicalsManagement.chemicalManager.dangerousPart;

import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xidian.zhiancloud.constant.DangerousManagementConstant;
import com.xidian.zhiancloud.dao.DangerousChemicalWarehouseOutMapper;
import com.xidian.zhiancloud.dao.syset.PositionMapper;
import com.xidian.zhiancloud.dao.syset.SysUserMapper;
import com.xidian.zhiancloud.dao.syset.usermanage.OrganizationMapper;
import com.xidian.zhiancloud.dto.ResultDTO;
import com.xidian.zhiancloud.enums.GeneralResponseEnums;
import com.xidian.zhiancloud.exception.CustomizeException;
import com.xidian.zhiancloud.model.DangerousChemicalInfo;
import com.xidian.zhiancloud.model.DangerousChemicalReviewRecord;
import com.xidian.zhiancloud.model.DangerousChemicalStorage;
import com.xidian.zhiancloud.model.DangerousChemicalWarehouseOut;
import com.xidian.zhiancloud.model.syset.Organization;
import com.xidian.zhiancloud.model.syset.PositionList;
import com.xidian.zhiancloud.model.syset.SysUser;
import com.xidian.zhiancloud.qo.chemicalsManagement.ApplyQO;
import com.xidian.zhiancloud.qo.chemicalsManagement.DangerousChemicalWarehouseQO;
import com.xidian.zhiancloud.service.chemicalsManagement.chemicalManager.CodeService;
import com.xidian.zhiancloud.service.user.usermanage.OrganizationService;
import com.xidian.zhiancloud.vo.chemicalsManagement.DangerousChemicalWarehouseOutVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.*;

/**
 * @Author: Egoist
 * @Date: 2020/11/10 17:00
 */

@Service
public class DangerousChemicalWarehouseOutService extends ServiceImpl<DangerousChemicalWarehouseOutMapper, DangerousChemicalWarehouseOut> implements IService<DangerousChemicalWarehouseOut> {

    @Autowired
    private DangerousChemicalWarehouseOutMapper dangerousChemicalWarehouseOutMapper;

    @Autowired
    private DangerousChemicalStorageService dangerousChemicalStorageService;

    @Autowired
    private DangerousChemicalInfoService dangerousChemicalInfoService;

    @Autowired
    private OrganizationMapper organizationMapper;

    @Autowired
    private OrganizationService organizationService;

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private CodeService codeService;

    @Autowired
    private PositionMapper positionMapper;

    @Autowired
    private DangerousChemicalReviewService dangerousChemicalReviewService;

    public IPage<DangerousChemicalWarehouseOutVO> getListByQO(DangerousChemicalWarehouseQO dangerousChemicalWarehouseQO, int state) {
        Page<DangerousChemicalWarehouseOutVO> page = new Page<>(dangerousChemicalWarehouseQO.getCurrent(), dangerousChemicalWarehouseQO.getSize());
        OrderItem orderItem = new OrderItem();
        orderItem.setColumn("apply_time").setAsc(false);
        page.getOrders().add(orderItem);
        IPage<DangerousChemicalWarehouseOutVO> iPage;
        switch (state) {
            //台账列表
            case 0:
                iPage = dangerousChemicalWarehouseOutMapper.getAccountListByQO(page, dangerousChemicalWarehouseQO);
                break;
            //申请列表
            case 1:
                iPage = dangerousChemicalWarehouseOutMapper.getApplyListByQO(page, dangerousChemicalWarehouseQO);
                break;
            //审核列表
            case 2:
                iPage = dangerousChemicalWarehouseOutMapper.getReviewListByQO(page, dangerousChemicalWarehouseQO);
                //从所有审核记录中过滤出当前用户所需审核的记录
                String reviewerId = dangerousChemicalWarehouseQO.getReviewerId().toString();
                List<DangerousChemicalWarehouseOutVO> allList = iPage.getRecords();
                List<DangerousChemicalWarehouseOutVO> satisfyList = new ArrayList<>();
                for (DangerousChemicalWarehouseOutVO vo : allList) {
                    String[] split = vo.getReviewerIds().split(",");
                    for (String s : split) {
                        if (reviewerId.equals(s)) {
                            satisfyList.add(vo);
                            break;
                        }
                    }
                }
                iPage.setRecords(satisfyList);
                break;
            //出库列表
            case 3:
                iPage = dangerousChemicalWarehouseOutMapper.getOutListByQO(page, dangerousChemicalWarehouseQO);
                break;
            //使用列表
            case 4:
                iPage = dangerousChemicalWarehouseOutMapper.getUseListByQO(page, dangerousChemicalWarehouseQO);
                break;
            //归还列表
            case 5:
                iPage = dangerousChemicalWarehouseOutMapper.getReturnListByQO(page, dangerousChemicalWarehouseQO);
                break;
            default:
                iPage = dangerousChemicalWarehouseOutMapper.getAccountListByQO(page, dangerousChemicalWarehouseQO);
        }
        List<DangerousChemicalWarehouseOutVO> records = iPage.getRecords();
        List<DangerousChemicalWarehouseOutVO> ans = new ArrayList<>();
        records.forEach(t -> {
            String strQuantity = "";
            if (state == 1 || state == 2 || state == 3) {
                strQuantity = t.getApplyQuantity().toString();
            } else {
                strQuantity = t.getRealQuantity().toString();
            }
            t.setStrOutQuantity(strQuantity + DangerousManagementConstant.QuantityUnit.get(t.getUnit()));
            ans.add(t);
        });
        iPage.setRecords(ans);
        return iPage;
    }


    public DangerousChemicalWarehouseOutVO getVOById(Long id) {
        DangerousChemicalWarehouseOut dangerousChemicalWarehouseOut = getById(id);
        if (dangerousChemicalWarehouseOut == null) {
            throw new CustomizeException(GeneralResponseEnums.GET_FAILED);
        }
        DangerousChemicalWarehouseOutVO dangerousChemicalWarehouseOutVO = new DangerousChemicalWarehouseOutVO();
        BeanUtils.copyProperties(dangerousChemicalWarehouseOut, dangerousChemicalWarehouseOutVO);
        Long storageId = dangerousChemicalWarehouseOut.getStorageId();
        DangerousChemicalStorage dangerousChemicalStorage = dangerousChemicalStorageService.getById(storageId);
        Long chemicalId = dangerousChemicalStorage.getChemicalId();
        Long organizationId = dangerousChemicalStorage.getOrganizationId();
        Long managerId = dangerousChemicalStorage.getManagerId();
        Long positionId = dangerousChemicalStorage.getPositionId();

        dangerousChemicalWarehouseOutVO.setChemicalId(chemicalId);
        dangerousChemicalWarehouseOutVO.setOrganizationId(organizationId);
        dangerousChemicalWarehouseOutVO.setManagerId(managerId);
        dangerousChemicalWarehouseOutVO.setPositionId(positionId);

        DangerousChemicalInfo dangerousChemicalInfo = dangerousChemicalInfoService.getById(chemicalId);
        dangerousChemicalWarehouseOutVO.setChemicalName(dangerousChemicalInfo == null ? "该危化品信息已删除" : dangerousChemicalInfo.getName());

        Organization organization = organizationMapper.selectById(organizationId);
        dangerousChemicalWarehouseOutVO.setOrganizationName(organization == null ? "该部门已删除" : organization.getName());

        SysUser sysUser = sysUserMapper.selectById(managerId);
        dangerousChemicalWarehouseOutVO.setManagerName(sysUser == null ? "该人员已删除" : sysUser.getName());

        return dangerousChemicalWarehouseOutVO;
    }

    public ResultDTO<Boolean> submitById(Long id) {
        DangerousChemicalWarehouseOut out = getById(id);
        DangerousChemicalStorage storage = dangerousChemicalStorageService.getById(out.getStorageId());
        BigDecimal storageQuantity = storage.getStorageQuantity();
        BigDecimal applyQuantity = out.getApplyQuantity();
        //如果申请量大于现有库存则返回false
        if (applyQuantity.compareTo(storageQuantity) == 1) {
            return ResultDTO.errorOf(-1, "申请量超出库存!");
        }
        DangerousChemicalWarehouseOut dangerousChemicalWarehouseOut = new DangerousChemicalWarehouseOut();
        dangerousChemicalWarehouseOut.setId(id);
        dangerousChemicalWarehouseOut.setState(1);
        dangerousChemicalWarehouseOut.setOuterId(storage.getManagerId());

        return ResultDTO.successOf(updateById(dangerousChemicalWarehouseOut), GeneralResponseEnums.SUCCESS);
    }

    public ResultDTO<Boolean> distributionById(DangerousChemicalWarehouseOut dangerousChemicalWarehouseOut) {
        dangerousChemicalWarehouseOut.setOutTime(new Date(System.currentTimeMillis()));
        dangerousChemicalWarehouseOut.setState(3);

        //设置出库编码
        String code = codeService.getChemicalOutCode(dangerousChemicalWarehouseOut.getCompanyId());
        dangerousChemicalWarehouseOut.setOutCode(code);

        //减少库存量
        DangerousChemicalWarehouseOut byId = getById(dangerousChemicalWarehouseOut.getId());
        Long storageId = byId.getStorageId();
        DangerousChemicalStorage dangerousChemicalStorage = dangerousChemicalStorageService.getById(storageId);
        BigDecimal storageQuantity = dangerousChemicalStorage.getStorageQuantity();
        BigDecimal realQuantity = dangerousChemicalWarehouseOut.getRealQuantity();
        //如果发放量大于库存则返回false
        if (realQuantity.compareTo(storageQuantity) == 1) {
            return ResultDTO.errorOf(-1, "发放量超出库存!");
        }
        dangerousChemicalStorage.setStorageQuantity(storageQuantity.subtract(realQuantity));
        dangerousChemicalStorageService.updateById(dangerousChemicalStorage);

        return ResultDTO.successOf(updateById(dangerousChemicalWarehouseOut), GeneralResponseEnums.SUCCESS);
    }

    public Boolean returnById(DangerousChemicalWarehouseOut dangerousChemicalWarehouseOut, Long userId) {
        DangerousChemicalWarehouseOut dcwo = getById(dangerousChemicalWarehouseOut.getId());
        DangerousChemicalStorage dangerousChemicalStorage = dangerousChemicalStorageService.getById(dcwo.getStorageId());
        dangerousChemicalStorage.setId(null);
        dangerousChemicalStorage.setStorageQuantity(dangerousChemicalWarehouseOut.getRealReturnQuantity());
        dangerousChemicalStorage.setCreateTime(new Date(System.currentTimeMillis()));
        updateById(dangerousChemicalWarehouseOut);
        return dangerousChemicalStorageService.addOrUpdate(dangerousChemicalStorage, userId);
    }


    public Boolean export(HttpServletResponse response, Long[] ids) throws IOException {
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        String fileName = URLEncoder.encode("危化品出库台账", "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
        List<DangerousChemicalWarehouseOut> list = listByIds(Arrays.asList(ids));
        List<DangerousChemicalWarehouseOutVO> ans = new LinkedList<>();
        System.out.println(list.toString());
        for (DangerousChemicalWarehouseOut t : list) {
            DangerousChemicalWarehouseOutVO vo = new DangerousChemicalWarehouseOutVO();
            BeanUtils.copyProperties(t, vo);
            SysUser applicantUser = sysUserMapper.selectById(vo.getApplicantId());
            SysUser outUser = sysUserMapper.selectById(vo.getOuterId());
            DangerousChemicalStorage storage = dangerousChemicalStorageService.getById(vo.getStorageId());
            DangerousChemicalInfo info = dangerousChemicalInfoService.getById(storage.getChemicalId());
            String unit = "";
            if (info != null) {
                unit = DangerousManagementConstant.QuantityUnit.get(info.getUnit());
            }

            vo.setApplicant(applicantUser == null ? "该用户已删除" : applicantUser.getName());
            vo.setOuterName(outUser == null ? "该用户已删除" : outUser.getName());
            vo.setStrOutQuantity(vo.getRealQuantity().toString() + unit);
            vo.setChemicalCode(info == null ? "危化品信息已删除" : info.getCode());
            vo.setChemicalName(info == null ? "危化品信息已删除" : info.getName());
            vo.setAlias(info == null ? "危化品信息已删除" : info.getAlias());
            ans.add(vo);
        }

        EasyExcel.write(response.getOutputStream(), DangerousChemicalWarehouseOutVO.class).sheet("模板").doWrite(ans);
        return true;
    }

    public Map<Long, String> getStorageNameList(Long companyId) {
        Map<Long, String> map = new HashMap<>();
        LambdaQueryWrapper<DangerousChemicalStorage> query = Wrappers.<DangerousChemicalStorage>lambdaQuery();
        query.eq(DangerousChemicalStorage::getCompanyId, companyId);
        List<DangerousChemicalStorage> list = dangerousChemicalStorageService.list(query);
        list.forEach(t -> {
            Long chemicalId = t.getChemicalId();
            DangerousChemicalInfo chemicalInfo = dangerousChemicalInfoService.getById(chemicalId);
            map.put(chemicalId, chemicalInfo.getName());
        });
        return map;
    }

    public List<Map<Long, String>> getOMPListByName(String chemicalName, Long companyId) {
        Map<Long, String> orgMap = new HashMap<>();
        Map<Long, String> magMap = new HashMap<>();
        Map<Long, String> posMap = new HashMap<>();

        Long chemicalInfoId = dangerousChemicalInfoService.getChemicalInfoIdByName(chemicalName);
        QueryWrapper<DangerousChemicalStorage> query = new QueryWrapper<DangerousChemicalStorage>();
        query.eq("company_id", companyId).eq("chemical_id", chemicalInfoId);
        List<DangerousChemicalStorage> storageList = dangerousChemicalStorageService.list(query);

        for (DangerousChemicalStorage storage : storageList) {
            Long organizationId = storage.getOrganizationId();
            Long managerId = storage.getManagerId();
            Long positionId = storage.getPositionId();

            String orgName = organizationService.getById(organizationId).getName();
            String magName = sysUserMapper.selectById(managerId).getName();
            String posName = positionMapper.selectById(positionId).getName();

            orgMap.put(organizationId, orgName);
            magMap.put(managerId, magName);
            posMap.put(positionId, posName);
        }
        List<Map<Long, String>> list = new ArrayList<>();
        list.add(orgMap);
        list.add(magMap);
        list.add(posMap);

        return list;
    }

    public Long getStorageId(ApplyQO qo) {
        QueryWrapper<DangerousChemicalStorage> query = new QueryWrapper<DangerousChemicalStorage>();
        query.eq("company_id", qo.getCompanyId()).eq("chemical_id", qo.getChemicalId())
                .eq("organization_id", qo.getOrganizationId()).eq("manager_id", qo.getManagerId())
                .eq("position_id", qo.getPositionId());
        List<DangerousChemicalStorage> list = dangerousChemicalStorageService.list(query);
        if (list != null) {
            return list.get(0).getId();
        }
        return null;
    }

    public Map<Long, String> getApplyOrgList(ApplyQO qo) {
        Map<Long, String> orgMap = new HashMap<>();
        QueryWrapper<DangerousChemicalStorage> query = new QueryWrapper<DangerousChemicalStorage>();
        query.eq("chemical_id", qo.getChemicalId()).eq("company_id", qo.getCompanyId());
        List<DangerousChemicalStorage> storages = dangerousChemicalStorageService.list(query);
        for (DangerousChemicalStorage storage : storages) {
            Organization org = organizationService.getById(storage.getOrganizationId());
            orgMap.put(storage.getOrganizationId(), org == null ? "该部门已删除" : org.getName());
        }
        return orgMap;
    }

    public Map<Long, String> getApplyPosList(ApplyQO qo) {
        Map<Long, String> posMap = new HashMap<>();
        QueryWrapper<DangerousChemicalStorage> query = new QueryWrapper<DangerousChemicalStorage>();
        query.eq("chemical_id", qo.getChemicalId()).eq("company_id", qo.getCompanyId()).
                eq("organization_id", qo.getOrganizationId());
        List<DangerousChemicalStorage> storages = dangerousChemicalStorageService.list(query);
        for (DangerousChemicalStorage storage : storages) {
            PositionList pos = positionMapper.selectById(storage.getPositionId());
            posMap.put(storage.getPositionId(), pos == null ? "该用户已删除!" : pos.getName());
        }
        return posMap;
    }


    public Map<Long, String> getApplyMagList(ApplyQO qo) {
        Map<Long, String> magMap = new HashMap<>();
        QueryWrapper<DangerousChemicalStorage> query = new QueryWrapper<DangerousChemicalStorage>();
        query.eq("chemical_id", qo.getChemicalId()).eq("company_id", qo.getCompanyId()).
                eq("organization_id", qo.getOrganizationId()).eq("position_id", qo.getPositionId());
        List<DangerousChemicalStorage> storages = dangerousChemicalStorageService.list(query);
        for (DangerousChemicalStorage storage : storages) {
            SysUser mag = sysUserMapper.selectById(storage.getManagerId());
            magMap.put(storage.getManagerId(), mag == null ? "该用户已删除!" : mag.getName());
        }
        return magMap;
    }


    public ResultDTO<Boolean> usageEntryById(DangerousChemicalWarehouseOut dangerousChemicalWarehouseOut) {
        DangerousChemicalWarehouseOut out = getById(dangerousChemicalWarehouseOut.getId());
        BigDecimal consumeQuantity = dangerousChemicalWarehouseOut.getConsumeQuantity();
        BigDecimal scrapQuantity = dangerousChemicalWarehouseOut.getScrapQuantity();
        BigDecimal returnQuantity = dangerousChemicalWarehouseOut.getReturnQuantity();
        BigDecimal realQuantity = out.getRealQuantity();
        BigDecimal usageQuantity = consumeQuantity.add(scrapQuantity).add(returnQuantity);

        if (usageQuantity.compareTo(realQuantity) != 0) {
            return ResultDTO.errorOf(-1, "录入数量与实际领取量不一致!");
        }
        return ResultDTO.successOf(updateById(dangerousChemicalWarehouseOut), GeneralResponseEnums.SUCCESS);
    }

    public Boolean patchById(DangerousChemicalWarehouseOut newInfo, Long patchUserId) {
        Long id = newInfo.getId();
        DangerousChemicalWarehouseOut oldInfo = getById(id);
        // 当审批时生成审批流程
        if (oldInfo.getState() == 1) {
            String reviewerIds = oldInfo.getReviewerIds();
            String[] split = reviewerIds.split(",");
            for (String s : split) {
                Long reviewerId = Long.valueOf(s);
                DangerousChemicalReviewRecord reviewRecord = new DangerousChemicalReviewRecord();
                SysUser reviewer = sysUserMapper.selectById(reviewerId);
                reviewRecord.setReviewerName(reviewer==null?"该用户已删除":reviewer.getName());
                reviewRecord.setCompanyId(oldInfo.getCompanyId());
                reviewRecord.setOutId(oldInfo.getId());
                assert reviewer != null;
                if (reviewer.getId().equals(patchUserId)){
                    reviewRecord.setOpinion(newInfo.getOpinion());
                    reviewRecord.setResult(newInfo.getState()==-1?"已退回":"已通过");
                    reviewRecord.setReviewTime(new Date(System.currentTimeMillis()));
                }
                dangerousChemicalReviewService.save(reviewRecord);
            }
        }
        return updateById(newInfo);
    }
}
